package com.hui.server.config.security;

import com.hui.server.filter.*;
import com.hui.server.config.jwt.JwtAuthenticationTokenFilter;
import com.hui.server.config.jwt.MyAccessDeniedHandler;
import com.hui.server.config.jwt.MyAuthenticationEntryPoint;
//import com.hui.server.service.impl.MyUserDetailsService;
import com.hui.server.service.impl.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @BelongsProject: yeb
 * @BelongsPackage: com.hui.server.config.security
 * @Author: HUI
 * @CreateTime: 2022-04-03 13:26
 * @Description: SpringSecurity 配置类
 */

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /*    @Autowired
        private AdminService adminService;


        /**
         * 重写 UserDetailsService
         *
         * @return
         * @throws Exception
         *//*
    @Override
    @Bean
    public UserDetailsService userDetailsService() {
        return username -> {
            Admin admin = adminService.getAdminByUserName(username);
            if (admin != null) {
//                admin.setRoles(adminService.getRolesByAdminId(admin.getId()));
                return admin;
            }
            return null;
        };
    }
*/
    //自定义无权访问类
    @Autowired
    private MyAccessDeniedHandler myAccessDeniedHandler;

    //自定义认证失败
    @Autowired
    private MyAuthenticationEntryPoint myAuthenticationEntryPoint;

    //用户认证
    @Autowired
    private MyUserDetailsService myUserDetailsService;

    //权限控制：根据请求的URL获取所对应需要的角色role
    @Autowired
    private CustomFilter customFilter;

    //权限控制：根据URL所需要的权限判断用户是否可以访问
    @Autowired
    private CustomUrlDecisionManager customUrlDecisionManager;


    @Bean
    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
        return new JwtAuthenticationTokenFilter();
    }

    @Bean
    public PasswordEncoder getPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public MyFilterSecurityInterceptor getMyFilterSecurityInterceptor() {
        MyFilterSecurityInterceptor filter = new MyFilterSecurityInterceptor();
        filter.setSecurityMetadataSource(customFilter);
        filter.setAccessDecisionManager(customUrlDecisionManager);
        return filter;

    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService).passwordEncoder(getPasswordEncoder());
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf()
                .disable()
                //基于 token，不需要session
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                //允许登录访问
                .antMatchers("/login",
                        "/logout",
                        "/ws/**",
                        "/css/**",
                        "/js/**",
                        "/index.html",
                        "favicon.ico",

                        //swagger
                        "/swagger-ui.html",
                        "/swagger-ui/**",
                        "/swagger-resources/**",
                        "/v2/api-docs",
                        "/v3/api-docs",
                        "/webjars/**",

                        //验证码
                        "/captcha"
                )
                .permitAll()
                //其他请求都要认证
                .anyRequest()
                //动态权限配置
                .authenticated()
                .and()
                //禁用浏览器缓存，主要是禁用验证码图片的缓存，是在响应头中添加

                /*
                  headers.add(new Header(CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate"));
                  	headers.add(new Header(PRAGMA, "no-cache"));
                  	headers.add(new Header(EXPIRES, "0"));
                 */

                .headers()
                .cacheControl();

        //增加自定义权限授权拦截器
        http.addFilterBefore(getMyFilterSecurityInterceptor(), FilterSecurityInterceptor.class);
        //添加jwt登录授权过滤器
        http.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        //添加自定义未授权和未登录结果返回
        http.exceptionHandling()
                .accessDeniedHandler(myAccessDeniedHandler)
                .authenticationEntryPoint(myAuthenticationEntryPoint);


    }


}
